using System;
using System.Collections.Generic;
using System.Web.Script.Services;
using System.Web.Services;

using BM.Tools.WebControls.MForm.Controls.Additions;

/// <summary>
/// This is a class that provides communication between the server and AJAX script services
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class AutoComplete : WebService
{
    public const string MaxLowerThanMinIncomeErrorText = "Max monthly income is lower than max monthly income";

    public const string MaxLowerThanOneTwelthYearlyIncomeErrorText = "Max monthly income is lower than 1/12 yearly income";

    public const string MinHigherThanMaxIncomeErrorText = "Min monthly income higher than max monthly income";

    public const string MinHigherThanOneTwelthYearlyIncomeErrorText =
            "Min monthly income is higher than 1/12 yearly income";
    /// <summary>
    /// a dictionary of countries
    /// </summary>
    private static Dictionary<string, string> countries = new Dictionary<string, string>();

    /// <summary>
    /// Initializes static members of the <see cref="AutoComplete"/> class. 
    /// Fills in the countries
    /// </summary>
    static AutoComplete()
    {
        countries.Add("AL", "Albania");
        countries.Add("BU", "Bulgaria");
        countries.Add("CA", "Canada");
        countries.Add("CH", "China");
        countries.Add("DE", "Germany");
        countries.Add("EN", "England");
        countries.Add("I", "Italy");
        countries.Add("P", "Portugal");
        countries.Add("PL", "Poland");
        countries.Add("PR", "Puerto Rico");
        countries.Add("RU", "Russia");
        countries.Add("S", "Sweden");
        countries.Add("ZA", "Zambia");
    }

    /// <summary>
    /// an example script service to use with ServiceConstraint functionality
    /// maximal monthly income is checked against other parameters for validation purpose
    /// </summary>
    /// <param name="maxMonthlyIncome">
    /// The max monthly income.
    /// </param>
    /// <param name="minMonthlyIncome">
    /// The min monthly income.
    /// </param>
    /// <param name="yearlyIncome">
    /// The yearly income.
    /// </param>
    /// <returns>
    /// is max monthly income valid
    /// </returns>
    [WebMethod]
    [ScriptMethod]
    public ServiceConstraintResponse CheckMaxMonthlyIncome(decimal? maxMonthlyIncome, decimal? minMonthlyIncome, decimal? yearlyIncome)
    {
        var response = new ServiceConstraintResponse();
        if (minMonthlyIncome > maxMonthlyIncome)
        {
            response.ErrorText = MaxLowerThanMinIncomeErrorText;
            response.IsValid = false;            
        } 
        else if (maxMonthlyIncome < yearlyIncome / 12)
        {
            response.ErrorText = MaxLowerThanOneTwelthYearlyIncomeErrorText; 
            response.IsValid = false;            
        }
        return response;
    }

    /// <summary>
    /// an example script service to use with ServiceConstraint functionality
    /// minimal monthly income is checked against other parameters for validation purpose
    /// </summary>
    /// <param name="maxMonthlyIncome">
    /// The max monthly income.
    /// </param>
    /// <param name="minMonthlyIncome">
    /// The min monthly income.
    /// </param>
    /// <param name="yearlyIncome">
    /// The yearly income.
    /// </param>
    /// <returns>
    /// is min monthly income valid
    /// </returns>
    [WebMethod]
    [ScriptMethod]
    public ServiceConstraintResponse CheckMinMonthlyIncome(decimal? maxMonthlyIncome, decimal? minMonthlyIncome, decimal? yearlyIncome)
    {
        var response = new ServiceConstraintResponse();
        if (minMonthlyIncome > maxMonthlyIncome)
        {
            response.IsValid = false;
            response.ErrorText = MinHigherThanMaxIncomeErrorText;
        }
        else if (minMonthlyIncome > yearlyIncome / 12)
        {
            response.IsValid = false;
            response.ErrorText = MinHigherThanOneTwelthYearlyIncomeErrorText;
        }

        return response;
    }

    /// <summary>
    /// an example script service with session enabled
    /// notice the [WebMethod(true)] tag
    /// </summary>
    /// <param name="now">
    /// The incoming integer value
    /// </param>
    /// <returns>
    /// is the current value valid
    /// </returns>
    [WebMethod(true)]
    [ScriptMethod]
    public ServiceConstraintResponse MustBeGreaterThanBefore(int now)
    {
        if (String.IsNullOrEmpty((string)Session["before"]))
        {
            Session["before"] = "0";
        }

        var response = new ServiceConstraintResponse();
        response.IsValid = now > Convert.ToInt32(Session["before"]);
        response.ErrorText = "Should be more than " + Session["before"];
        return response;
    }

    /// <summary>
    /// an example script service that returns the reverse of the string
    /// </summary>
    /// <param name="contextKey">
    /// The value to be changed (in order to conform to Dynamic Populate requirements, it has to be called contextKey)
    /// </param>
    /// <returns>
    /// a reverse of context key
    /// </returns>
    [WebMethod]
    [ScriptMethod]
    public string GetReverse(string contextKey)
    {
        var chars = new List<char>(contextKey.ToCharArray());
        chars.Reverse();
        return new string(chars.ToArray());        
    }

    /// <summary>
    /// finds the list of countries
    /// </summary>
    /// <param name="prefixText">
    /// The prefix text (the name must be preserved in order to match AutoComplete requirements)
    /// </param>
    /// <param name="count">
    /// The count (the name must be preserved in order to match AutoComplete requirements)
    /// </param>
    /// <returns>
    /// the array of countries that match prefix text
    /// </returns>
    [WebMethod]
    [ScriptMethod]
    public string[] GetCountries(string prefixText, int count)
    {
        var items = new List<string>();
        if (countries.ContainsKey(prefixText))
        {
            AddItem(items, countries[prefixText], prefixText);                        
        }        
                
        foreach (string value in countries.Keys)
        {
            string text = countries[value];
            if (text.Contains(prefixText))
            {
                AddItem(items, text, value);
            }
            if (items.Count >= count) break;
        }

        return items.ToArray();
    }

    /// <summary>
    /// adds the text and value pair into the collection of items
    /// </summary>
    /// <param name="items">
    /// The items list.
    /// </param>
    /// <param name="text">
    /// The text of the pair.
    /// </param>
    /// <param name="value">
    /// The value of the pair.
    /// </param>
    private static void AddItem(ICollection<string> items, string text, string value)
    {          
        items.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(text, value));
    }
}